﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="KinectElevationControl.xaml.cs" company="arvystate.net">
//   arvystate.net
// </copyright>
// <summary>
//   The elevation event handler.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace PresentationAid.Control
{
    using System;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media.Imaging;

    using NLog;

    /// <summary>
    /// The elevation event handler.
    /// </summary>
    /// <param name="sender">
    /// The sender.
    /// </param>
    /// <param name="e">
    /// The e.
    /// </param>
    public delegate void ElevationEventHandler(object sender, EventArgs e);

    /// <summary>
    /// Interaction logic for KinectElevationControl
    /// </summary>
    public partial class KinectElevationControl
    {
        #region Static Fields

        /// <summary>
        /// The logger.
        /// </summary>
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        #endregion

        #region Fields

        /// <summary>
        /// The _elevation angle.
        /// </summary>
        private int elevationAngle;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="KinectElevationControl"/> class.
        /// </summary>
        public KinectElevationControl()
        {
            Logger.Trace("Init: KinectElevationControl");

            this.InitializeComponent();

            this.IsEnabledChanged += this.OnIsEnabledChanged;
        }

        #endregion

        #region Public Events

        /// <summary>
        /// The elevation changed.
        /// </summary>
        public event ElevationEventHandler ElevationChanged;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the elevation angle.
        /// </summary>
        public int ElevationAngle
        {
            get
            {
                return this.elevationAngle;
            }

            set
            {
                this.elevationAngle = value;
                this.Transform.Angle = value * -1.5;
                this.ElevationLabel.Text = value + "°";
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// The on is enabled changed.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="dependencyPropertyChangedEventArgs">
        /// The dependency property changed event args.
        /// </param>
        private void OnIsEnabledChanged(
            object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            if (this.IsEnabled)
            {
                this.Slider.Source =
                    new BitmapImage(
                        new Uri(
                            "/PresentationAid;component/Resources/Images/ElevationControl/slider.png", 
                            UriKind.RelativeOrAbsolute));
                this.SliderTrack.Source =
                    new BitmapImage(
                        new Uri(
                            "/PresentationAid;component/Resources/Images/ElevationControl/slider-track.png", 
                            UriKind.RelativeOrAbsolute));
                this.Tilt.Source =
                    new BitmapImage(
                        new Uri(
                            "/PresentationAid;component/Resources/Images/ElevationControl/tilt.png", 
                            UriKind.RelativeOrAbsolute));
            }
            else
            {
                this.Slider.Source =
                    new BitmapImage(
                        new Uri(
                            "/PresentationAid;component/Resources/Images/ElevationControl/slider-disabled.png", 
                            UriKind.RelativeOrAbsolute));
                this.SliderTrack.Source =
                    new BitmapImage(
                        new Uri(
                            "/PresentationAid;component/Resources/Images/ElevationControl/slider-track-disabled.png", 
                            UriKind.RelativeOrAbsolute));
                this.Tilt.Source =
                    new BitmapImage(
                        new Uri(
                            "/PresentationAid;component/Resources/Images/ElevationControl/tilt-disabled.png", 
                            UriKind.RelativeOrAbsolute));
            }
        }

        /// <summary>
        /// The slider mouse down.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void SliderMouseDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;

            if (fe == null)
            {
                return;
            }

            if (fe.CaptureMouse())
            {
                e.Handled = true;
            }
        }

        /// <summary>
        /// The slider mouse move.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void SliderMouseMove(object sender, MouseEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;

            if (fe == null)
            {
                return;
            }

            if (!fe.IsMouseCaptured)
            {
                return;
            }

            Point position = Mouse.GetPosition(this.SliderTrack);
            int newAngle = -27
                           + (int)
                             Math.Round(
                                 54.0 * (this.SliderTrack.ActualHeight - position.Y) / this.SliderTrack.ActualHeight);

            if (newAngle < -27)
            {
                newAngle = -27;
            }
            else if (newAngle > 27)
            {
                newAngle = 27;
            }

            this.ElevationAngle = newAngle;
            this.ElevationLabel.Text = newAngle + "°";
        }

        /// <summary>
        /// The slider mouse up.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void SliderMouseUp(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;

            if (fe == null)
            {
                return;
            }

            if (!fe.IsMouseCaptured)
            {
                return;
            }

            Logger.Info("Event: SliderMouseUp - ElevationAngle: {0}", this.ElevationAngle);

            fe.ReleaseMouseCapture();
            e.Handled = true;

            this.ElevationChanged(this, new EventArgs());
        }

        #endregion
    }
}